/*
 * Copyright (C) 2025 Thomas Akehurst
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.github.tomakehurst.wiremock.db.service.impl;

import com.github.tomakehurst.wiremock.db.entity.MultiMappingEntity;
import com.github.tomakehurst.wiremock.db.mapper.MultiMappingMapper;
import com.github.tomakehurst.wiremock.db.service.MultiMappingService;
import com.github.tomakehurst.wiremock.db.utils.MultiMappingConverter;
import com.github.tomakehurst.wiremock.stubbing.StubMapping;
import com.github.tomakehurst.wiremock.stubbing.StubMappingCollection;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.List;

/**
 * 多存根业务实现类
 * 实现 MultiMappingService 接口，封装 MyBatis 数据访问逻辑
 */
public class MultiMappingServiceImpl implements MultiMappingService {

    private static final Logger LOG = LoggerFactory.getLogger(MultiMappingServiceImpl.class);

    // 依赖注入：MyBatis会话工厂 + 转换器（避免硬编码，支持Mock测试）
    private final SqlSessionFactory sqlSessionFactory;
    private final MultiMappingConverter multiMappingConverter;

    /**
     * 构造器注入所有依赖（推荐通过Spring等框架自动注入）
     * @param sqlSessionFactory MyBatis会话工厂
     * @param multiMappingConverter 多存根实体转换器
     */
    public MultiMappingServiceImpl(SqlSessionFactory sqlSessionFactory, MultiMappingConverter multiMappingConverter) {
        this.sqlSessionFactory = sqlSessionFactory;
        this.multiMappingConverter = multiMappingConverter;
    }

    @Override
    public List<StubMapping> findAllAsStubMappings() {
        try (SqlSession session = sqlSessionFactory.openSession()) {
            MultiMappingMapper mapper = session.getMapper(MultiMappingMapper.class);
            List<MultiMappingEntity> entities = mapper.findAll();
            LOG.info("查询到 {} 个多存根文件", entities.size());

            // 委托转换器完成批量转换（Entity → StubMapping，扁平化处理）
            return multiMappingConverter.batchToStubMappings(entities);
        } catch (Exception e) {
            LOG.error("查询所有多存根文件失败", e);
            throw new RuntimeException("查询所有多存根文件失败：" + e.getMessage(), e);
        }
    }

    @Override
    public void deleteById(String id) {
        if (id == null || id.trim().isEmpty()) {
            throw new IllegalArgumentException("多存根文件ID不能为空");
        }

        try (SqlSession session = sqlSessionFactory.openSession(true)) {
            MultiMappingMapper mapper = session.getMapper(MultiMappingMapper.class);
            // 先校验多存根文件是否存在
            MultiMappingEntity entity = mapper.findById(id);
            if (entity == null) {
                LOG.warn("多存根文件不存在：id={}", id);
                throw new RuntimeException("多存根文件不存在：id=" + id);
            }

            mapper.deleteById(id);
            LOG.info("删除多存根文件成功：id={}", id);
        } catch (Exception e) {
            LOG.error("删除多存根文件失败：id={}", id, e);
            throw new RuntimeException("删除多存根文件失败：id=" + id, e);
        }
    }

    @Override
    public StubMappingCollection findCollectionById(String id) {
        if (id == null || id.trim().isEmpty()) {
            throw new IllegalArgumentException("多存根文件ID不能为空");
        }

        try (SqlSession session = sqlSessionFactory.openSession()) {
            MultiMappingMapper mapper = session.getMapper(MultiMappingMapper.class);
            MultiMappingEntity entity = mapper.findById(id);
            if (entity == null) {
                LOG.warn("多存根文件不存在：id={}", id);
                throw new RuntimeException("多存根文件不存在：id=" + id);
            }

            // 转换为完整集合结构（保留元信息，不扁平化）
            return multiMappingConverter.toCollection(entity);
        } catch (Exception e) {
            LOG.error("查询多存根文件详情失败：id={}", id, e);
            throw new RuntimeException("查询多存根文件详情失败：id=" + id, e);
        }
    }

    @Override
    public MultiMappingEntity findByStubId(String stubId) {
        if (stubId == null || stubId.trim().isEmpty()) {
            throw new IllegalArgumentException("单StubID不能为空");
        }

        try (SqlSession session = sqlSessionFactory.openSession()) {
            MultiMappingMapper mapper = session.getMapper(MultiMappingMapper.class);
            MultiMappingEntity entity = mapper.findByStubId(stubId);
            if (entity == null) {
                LOG.debug("未查询到单Stub关联的多存根文件：stubId={}", stubId);
                throw new RuntimeException("单Stub未关联多存根文件：stubId=" + stubId);
            }

            return entity;
        } catch (Exception e) {
            LOG.error("根据单StubID查询多存根文件失败：stubId={}", stubId, e);
            throw new RuntimeException("根据单StubID查询多存根文件失败：stubId=" + stubId, e);
        }
    }
}
    